// opt: 0
// flag: -g
// run: $exec < input
// run-: valgrind --leak-check=full $exec < input
#include <iostream>
#include <vector>

#define NDEBUG
#include <cassert>

template <class T>
struct node
{
	typedef T value_type;
	typedef int size_type;

	value_type value;
	size_type size;
	size_type size_all;
	size_type count;
	size_type left;
	size_type right;
};

// equal element handled separately.
template <class T>
struct size_balanced_tree
{
	typedef T value_type;
	typedef int size_type;

	size_balanced_tree(int max_size) : max_size(max_size)
	{
		sbt.resize(max_size);
		next_free.reserve(max_size);
		for (int i = 0; i < max_size; i++) next_free.push_back(i+1);
		current_free = 0;
		root = allocate();
	}

	void insert(value_type value, bool flag)
	{
		sbt[0].size = sbt[0].size_all = sbt[0].count = 0;
		insert_detail(root, value, flag);
	};

	value_type remove(value_type value) { return remove_detail(root, value).value; };
	value_type select_kth_small(size_type k) { return select_small_detail(root, k); };
	value_type select_kth_large(size_type k) { return select_large_detail(root, k); };
	size_type rank(value_type value) { return rank_detail(root, value); };

	value_type pred(value_type value) // less <
	{
		return sbt[pred_detail(root, 0, value)].value;
	}

	value_type succ(value_type value) // greater >
	{
		return sbt[succ_detail(root, 0, value)].value;
	}

	value_type get_min()
	{
		int x;
		for (x = root; sbt[x].left; x = sbt[x].left);
		return sbt[x].value;
	}

	value_type get_max()
	{
		int x;
		for (x = root; sbt[x].right; x = sbt[x].right);
		return sbt[x].value;
	}

	bool find(value_type value)
	{
		for (int x = root; x; ) {
			if (value == sbt[x].value) return true;
			if (value > sbt[x].value) x = sbt[x].right;
			else					  x = sbt[x].left;
		}
		return false;
	}

	void inorder()
#ifdef NDEBUG
	{}
#else
	{
		std::cerr << "in-tree: " << root_value() << "\n";
		inorder(root);
		std::cerr << '\n';
	}

	void inorder(size_type & x)
	{
		if (!x) return;
		else {
			inorder(sbt[x].left);
			std::cerr << "(" << sbt[x].value << " : " << sbt[x].count << ", " <<
				"sall: " << sbt[x].size_all << "  size: " << sbt[x].size << ")  " <<
					sbt[ sbt[x].left ].value << ' ' << sbt[ sbt[x].right ].value << '\n';
			inorder(sbt[x].right);
		}
	}

	int root_value() { return sbt[root].value; }

#endif

private:

	size_type allocate()
	{
		size_type tmp = current_free;
		current_free = next_free[current_free];
		return tmp;
	}

	void deallocate(size_type x)
	{
		next_free[x] = current_free;
		current_free = x;
	}

	void left_rot(size_type & x)
	{
		size_type y = sbt[x].right;
		sbt[x].right = sbt[y].left;
		sbt[y].left = x;
		sbt[y].size = sbt[x].size;
		sbt[y].size_all = sbt[x].size_all;
		sbt[x].size = sbt[sbt[x].left].size + sbt[sbt[x].right].size + 1;
		sbt[x].size_all = sbt[sbt[x].left].size_all + sbt[sbt[x].right].size_all + sbt[x].count;
		assert(sbt[x].count >= 0);
		x = y;
	}

	void right_rot(size_type & x)
	{
		size_type y = sbt[x].left;
		sbt[x].left = sbt[y].right;
		sbt[y].right = x;
		sbt[y].size = sbt[x].size;
		sbt[y].size_all = sbt[x].size_all;
		sbt[x].size = sbt[sbt[x].left].size + sbt[sbt[x].right].size + 1;
		sbt[x].size_all = sbt[sbt[x].left].size_all + sbt[sbt[x].right].size_all + sbt[x].count;
		assert(sbt[x].count >= 0);
		x = y;
	}

	void maintain(size_type & x, bool flag)
	{
		if (flag) {
			if (sbt[ sbt[ sbt[x].right ].right ].size > sbt[ sbt[x].left ].size)
				left_rot(x);
			else
			if (sbt[ sbt[ sbt[x].right ].left ].size > sbt[ sbt[x].left ].size) {
				right_rot(sbt[x].right);
				left_rot(x);
			} else
				return;
		} else {
			if (sbt[ sbt[ sbt[x].left ].left ].size > sbt[ sbt[x].right ].size)
				right_rot(x);
			else
			if (sbt[ sbt[ sbt[x].left].right ].size > sbt[ sbt[x].right ].size) {
				left_rot(sbt[x].left);
				right_rot(x);
			} else
				return;
		}
		maintain(sbt[x].left, false);
		maintain(sbt[x].right, true);
		maintain(x, false);
		maintain(x, true);
	}

	// flag = true: value in tree, false: no value in tree
	void insert_detail(size_type & x, value_type value, bool flag)
	{
		assert(0 <= x && x <= max_size);
		if (!x) {
			x = allocate();
			sbt[x].left = sbt[x].right = 0;
			sbt[x].size = sbt[x].size_all = sbt[x].count = 1;
			sbt[x].value = value;
		} else {
			sbt[x].size_all++;
			if (!flag) sbt[x].size++;
			if (value < sbt[x].value)
				insert_detail(sbt[x].left, value, flag);
			else if (value > sbt[x].value)
				insert_detail(sbt[x].right, value, flag);
			else
				sbt[x].count++;
			if (!flag)
				maintain(x, value >= sbt[x].value);
		}
	}

	node<value_type> remove_detail(size_type & x, value_type value, bool flag = true)
	{
		assert(0 <= x && x <= max_size);
		node<value_type> d;
		if (!flag) sbt[x].size--;
		if ((value == sbt[x].value) || (value < sbt[x].value && !sbt[x].left)
				|| (value > sbt[x].value && !sbt[x].right)) {
			d = sbt[x];
			if (flag) {
				d.count = 1;
				sbt[x].count--;
				if (sbt[x].count) {
					sbt[x].size_all--;
					return d;
				}
				// delete one time lead to node disapper
				d.size = -1;
				sbt[x].size--;
			}
			if (sbt[x].left && sbt[x].right) {
				node<value_type> tmp = sbt[x];
				sbt[x] = remove_detail(sbt[x].left, sbt[x].value + 1, false);
				sbt[x].size = tmp.size;
				sbt[x].size_all = tmp.size_all;
			}
			else {
				deallocate(x);
				x = sbt[x].left + sbt[x].right;
			}
		}
		else if (value > sbt[x].value)
			d = remove_detail(sbt[x].right, value, flag);
		else
			d = remove_detail(sbt[x].left, value, flag);
		sbt[x].size_all -= d.count;
		if (flag && d.size < 0) sbt[x].size--;
		assert(d.value >= 0);
		return d;
	}

	value_type select_small_detail(size_type x, size_type k)
	{
		assert(0 <= x && x <= max_size);
		size_type l = sbt[ sbt[x].left ].size_all + 1;
		size_type r = sbt[ sbt[x].left ].size_all + sbt[x].count;
		if (l <= k && k <= r)
			return sbt[x].value;
		else
		if (r < k)
			return select_small_detail(sbt[x].right, k - r);
		else
			return select_small_detail(sbt[x].left, k);
	}

	value_type select_large_detail(size_type x, size_type k)
	{
		assert(0 <= x && x <= max_size);
		size_type l = sbt[ sbt[x].right ].size_all + 1;
		size_type r = sbt[ sbt[x].right ].size_all + sbt[x].count;
		if (l <= k && k <= r)
			return sbt[x].value;
		else
		if (r < k)
			return select_large_detail(sbt[x].left, k - r);
		else
			return select_large_detail(sbt[x].right, k);
	}

	size_type rank_detail(size_type x, value_type value) // FIXME
	{
		if (value < sbt[x].value)
			return rank_detail(sbt[x].left, value);
		else
		if (value > sbt[x].value)
			return rank_detail(sbt[x].right, value) + sbt[ sbt[x].left ].size + 1;
		return sbt[ sbt[x].left ].size + 1;
	}

	size_type pred_detail(size_type x, value_type y, value_type value)
	{
		if (!x) return y;
		if (sbt[x].value < value)
			return pred_detail(sbt[x].right, x, value);
		else
			return pred_detail(sbt[x].left, y, value);
	}

	size_type succ_detail(size_type x, value_type y, value_type value)
	{
		if (!x) return y;
		if (sbt[x].value > value)
			return succ_detail(sbt[x].right, x, value);
		else
			return succ_detail(sbt[x].left, y, value);
	}

	size_type max_size;
	size_type root;
	size_type current_free;
	std::vector<node<value_type> > sbt;
	std::vector<int> next_free;
};

int const maxn = 200007;
int father[maxn], size[maxn];

int get_father(int x)
{
	return (x == father[x]) ? x : (father[x] = get_father(father[x]));
}

void set_union(int x, int y)
{
	size[father[x]] += size[father[y]];
	father[y] = father[x];
}

int main()
{
	std::ios::sync_with_stdio(false);
	int n, m;
	std::cin >> n >> m;
	for (int i = 1; i <= n; i++) { father[i] = i; size[i] = 1; }
	size_balanced_tree<int> tree(n+1);
	tree.insert(1, false);
	for (int i = 1; i < n; i++) tree.insert(1, true);
	tree.inorder();

	for (int i = 0, opt, x, y; i < m; i++) {
		std::cin >> opt;
		if (opt) {
			std::cin >> x;
			std::cout << tree.select_kth_large(x) << '\n';
		} else {
			std::cin >> x >> y;
			int f1 = get_father(x);
			int f2 = get_father(y);
			if (f1 == f2) continue;
			tree.remove(size[f1]);
			tree.remove(size[f2]);
			tree.insert(size[f1] + size[f2], tree.find(size[f1] + size[f2]));
			set_union(f1, f2);

			tree.inorder();
		}
	}
}

